#include "NativeEventFilter.h"

#include <qaudiorecorder.h>
#include <qurl.h>
#include <windows.h>

#include <QAudioDeviceInfo>
#include <QAudioRecorder>
#include <iostream>

using std::cout;
using std::endl;

Keyboard::Keyboard() {}

void Keyboard::addHotKey(quint32 mod, quint32 key) {
    int id = mod ^ key;
    BOOL ok = RegisterHotKey(0, id, mod, key);
    if (!ok) std::cerr << "register shortcut failed!" << std::endl;
}

bool Keyboard::nativeEventFilter(const QByteArray &eventType, void *message,
                                 long *result) {
    MSG *msg = static_cast<MSG *>(message);
    if (msg->message == WM_HOTKEY) {
        const quint32 keycode = HIWORD(msg->lParam);
        const quint32 modifiers = LOWORD(msg->lParam);

        if (modifiers == MOD_CONTROL) {
            switch (keycode) {
                case '0': {
                    ::cout << "begin record voice" << ::endl;
                    Worker::getInstance().record();
                    break;
                }
                case 'V': {
                    cout << "stop record" << endl;
                    break;
                }
            }
        }
    }

    return true;
}

const Worker &Worker::getInstance() {
    static Worker w;
    return w;
}

void Worker::record() const {
    QAudioDeviceInfo info =
        QAudioDeviceInfo::availableDevices(QAudio::AudioInput).at(0);
    QAudioRecorder *recorder = new QAudioRecorder();
    QAudioEncoderSettings settings = recorder->audioSettings();

    settings.setCodec("audio/PCM");  // 这些是QAudioRecorder是设置，见名思意
    settings.setBitRate(96000);
    // settings.setSampleRate(44100);
    settings.setChannelCount(2);
    settings.setQuality(QMultimedia::EncodingQuality::HighQuality);
    settings.setEncodingMode(QMultimedia::ConstantQualityEncoding);
    recorder->setAudioSettings(settings);
    recorder->setAudioInput(info.deviceName());
    recorder->setOutputLocation(QUrl("input.wav"));
    recorder->setContainerFormat("audio/wav");
    recorder->record();
}

void Worker::stopAndTransfer() {}
